package fr.contacts.controllers;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.IdClass;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import fr.contacts.constant.Constant;
import fr.contacts.models.Adresse;
import fr.contacts.models.Contact;

@SessionAttributes({"contact", "adresse"})
@Controller
public class CreateController {
	
	private int contactId = 0;
	private int adresseId = 0;
	
    @RequestMapping(value = "/contact/create")
    public String create(
    		@RequestParam("nom") String nom, 
    		@RequestParam("prenom") String prenom,
    		@RequestParam("email") String email,
    		@RequestParam("day") String day,
    		@RequestParam("month") String month,
    		@RequestParam("year") String year,
    		@RequestParam("enable") String enable,
    		@RequestParam("typeAdresse") String typeAdresse,
    		@RequestParam("numeroRue") String numeroRue,
    		@RequestParam("rue") String rue,
    		@RequestParam("codePostal") String codePostal,
    		@RequestParam("ville") String ville,
    		Model model) throws ParseException {
    
    		Constant.clearErrorList();
    	
    		System.out.println("CreateController: Passing through...");
    		Date dateDeNaissance = createDateNaissance(day, month, year);
    		Adresse adresse = createAdresse(typeAdresse, numeroRue, rue, codePostal, ville);
    		Contact contact = createContact(nom, prenom, email, dateDeNaissance, enable);
    		
    		
    		
    		if ( !Constant.errorList.isEmpty() ) {
    			model.addAttribute("user_action", "create");
    			model.addAttribute("contact", contact);
    			if (adresse != null) {
    				model.addAttribute("adresse", adresse);
    			}
    			model.addAttribute("errors", Constant.errorList);
    			return "/WEB-INF/views/create.jsp";
    		}
    		
    		int contactIdTemp = ++contactId;
    	//	ContactsDAO.createContact(contactIdTemp, nom, prenom, email, dateDeNaissance, enable.equals("enable"), adresse);
    		ContactsDAO.addContact(contact, adresse, contactIdTemp);
    		
    		Contact contactCreated = ContactsDAO.readContact(contactIdTemp);
    		List<Adresse> adresseList = ContactsDAO.readAllAdresse(contactIdTemp);
    		model.addAttribute("contact", contactCreated);
    		model.addAttribute("adresseList", adresseList);
    		
    		return "redirect:/contact?id="+contactCreated.getId() /*/WEB-INF/views/contact.jsp"*/;
    }
    
    @RequestMapping(value = "/contact/new")
    public String showForm(Model model) {
    	
    	Constant.clearErrorList();
    	
    	model.addAttribute("contact", new Contact());
    	model.addAttribute("adresse", new Adresse());
    	model.addAttribute("user_action", "create");
    	return "/WEB-INF/views/create.jsp";
    	
    }
    
    
    @RequestMapping( value = "/contact/update",  method = RequestMethod.POST )
	public String update(@ModelAttribute("contact") Contact contact,
						Model model, SessionStatus sessionStatus,
						@RequestParam("nom") String nom, 
			    		@RequestParam("prenom") String prenom,
			    		@RequestParam("email") String email,
			    		@RequestParam("day") String day,
			    		@RequestParam("month") String month,
			    		@RequestParam("year") String year,
			    		@RequestParam("enable") String enable) throws ParseException {
    	
    	Constant.clearErrorList();
		
		System.out.println("EditContact : UPDATE passing through ...");
	//	sessionStatus.setComplete();
		Date newDate = createDateNaissance(day, month, year);
		int idContactTemp = contact.getId();
		contact = createContact(nom, prenom, email, newDate, enable);
		contact.setId(idContactTemp);
		if(Constant.errorList.isEmpty()) {
			ContactsDAO.readContact(idContactTemp).setDateDeNaissance(newDate);
			ContactsDAO.readContact(idContactTemp).setNom(nom);
			ContactsDAO.readContact(idContactTemp).setPrenom(prenom);
			ContactsDAO.readContact(idContactTemp).setEmail(email);
			ContactsDAO.readContact(idContactTemp).setActif(enable.equals("enable"));
			sessionStatus.setComplete();			
			return "redirect:/contact?id=" + contact.getId();
		}
	
		
		model.addAttribute("contact", contact);
		model.addAttribute("adresses", ContactsDAO.readAllAdresse(contact.getId()));
		model.addAttribute("user_action", "edit");

		Calendar cal = Calendar.getInstance();
		cal.setTime(contact.getDate());
		model.addAttribute("dayParam", String.valueOf(cal.get(Calendar.DAY_OF_MONTH)));
		model.addAttribute("monthParam", convertMonth(cal.get(Calendar.MONTH) + 1));
		model.addAttribute("yearParam", cal.get(Calendar.YEAR));
		
		return "/WEB-INF/views/create.jsp";
		
		
	}
    
    @RequestMapping( value = "/contact/adresse/update",  method = RequestMethod.POST )
	public String update(@ModelAttribute("contact") Contact contact,
						 @ModelAttribute("adresse") Adresse adresse,
						 Model model, SessionStatus sessionStatus,
				    		@RequestParam("typeAdresse") String typeAdresse,
				    		@RequestParam("numeroRue") String numeroRue,
				    		@RequestParam("rue") String rue,
				    		@RequestParam("codePostal") String codePostal,
				    		@RequestParam("ville") String ville) throws ParseException {
    	
    	Constant.clearErrorList();
		
		System.out.println("EditContact : UPDATE passing through ...");
		
		Adresse newAdresse = createAdresse(typeAdresse, numeroRue, rue, codePostal, ville);
		System.out.println(contact);
		System.out.println(adresse);
		boolean isOk = checkAdresse(contact.getId(), typeAdresse, "update", adresse.getType());
		
		if ( newAdresse != null && isOk) {
			System.out.println("UPDATE Adresse !");
			ContactsDAO.readAdresse(contact.getId(), adresse.getId()).setCodePostal(codePostal);
			ContactsDAO.readAdresse(contact.getId(), adresse.getId()).setNumero(numeroRue);
			ContactsDAO.readAdresse(contact.getId(), adresse.getId()).setRue(rue);
			ContactsDAO.readAdresse(contact.getId(), adresse.getId()).setVille(ville);
			ContactsDAO.readAdresse(contact.getId(), adresse.getId()).setType(typeAdresse);

			sessionStatus.setComplete();
			return "redirect:/contact?id=" + contact.getId();
		}
		if (!isOk) {
			Constant.addError("Il y a déjà une adresse de facturation");
		}
		
		model.addAttribute("contact", contact);
		model.addAttribute("adresse", adresse);
		
		return "redirect:/contact/adresse/edit?id=" + contact.getId() + "&idAdresse=" + adresse.getId();
		
	}
    
    public boolean checkAdresse(int contactIdParam, String typeAdresseParam, String action, String typeAdresseBase) {
    	if (typeAdresseParam.equals("livraison")) {
    		return true;
    	}
    	else {
	    	List<Adresse> adresseList = ContactsDAO.readAllAdresse(contactIdParam);
	    	int count = 0;
	    	for (Adresse adresse : adresseList) {
	    		System.out.println("Adresse type : " + adresse.getType());
	    		if (adresse.getType().equals("facturation")) {
	    			count++;
	    		}
	    	}
	    	
	    	System.out.println("Count : " + count);
	    	if (action.equals("create")) {
	    		return (count == 0);
	    	}
	    	else if (action.equals("update")) {
	    		if (typeAdresseBase.equals("facturation")) {
	    			return (count == 1);
	    		}
	    		else {
	    			return (count == 0);
	    		}
	    	}
	    	else {
	    		return false;
	    	}
    	}
    }
    
    @RequestMapping( value = "/contact/adresse/new" )
    public String newAdresse(@ModelAttribute("contact") Contact contact,
			 				 Model model ){
    	Constant.clearErrorList();
    	
    	model.addAttribute("contact", contact);
    	model.addAttribute("adresse", new Adresse());
    	model.addAttribute("user_action", "create");
    	
    	return "/WEB-INF/views/adresseform.jsp";
    }
    
    @RequestMapping( value = "/contact/adresse/create",  method = RequestMethod.POST)
    public String addAdresse(@ModelAttribute("contact") Contact contact,
			 				 @ModelAttribute("adresse") Adresse adresse,
			 				 Model model, SessionStatus sessionStatus,
			 				 @RequestParam("typeAdresse") String typeAdresse,
			 				 @RequestParam("numeroRue") String numeroRue,
			 				 @RequestParam("rue") String rue,
			 				 @RequestParam("codePostal") String codePostal,
			 				 @RequestParam("ville") String ville) {
    	
    	Constant.clearErrorList();
    	
    	boolean isOk;
    	if (typeAdresse.equals("facturation")) {
    		isOk = checkAdresse(contact.getId(), typeAdresse, "create", null);
    	}
    	else if (typeAdresse.equals("livraison")) {
    		isOk = true;
    	}
    	else {
    		Constant.addError("Le type d'adresse " + typeAdresse + " n'existe pas !");
    		model.addAttribute("contact", contact);
    		model.addAttribute("adresse", adresse);
    		return "redirect:/contact/adresse/create";
    	}
    	if (isOk) {
	    	int adresseIdTemp = ++adresseId;
	    	adresse.setId(adresseIdTemp);
	    	adresse.setType(typeAdresse);
	    	adresse.setNumero(numeroRue);
	    	ContactsDAO.addAdresse(contact.getId(), adresse);    	
	    	sessionStatus.setComplete();
    	}
    	else {
    		Constant.addError("Il y a déjà une adresse de facturation");
    	}
    	return "redirect:/contact?id=" + contact.getId();
    }
    
    private Contact createContact(String nom, String prenom, String email, Date date, String enable) {
    	
    	Contact c = new Contact();
    	if ( nom.isEmpty() && prenom.isEmpty() && email.isEmpty() ) {
    		Constant.addError("Nom, Prenom ou email doivent être renseignés !");
    	}
    	
    	c.setNom(nom);
    	c.setPrenom(prenom);
    	c.setEmail(email);
    	c.setDateDeNaissance(date);
    	c.setActif(enable.equals("enable"));
    	
		return c;
	}
    

	private Date createDateNaissance(String dayParam, String monthParam, String yearParam) throws ParseException {
    	DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
    	
    	if(dayParam.isEmpty() && monthParam.isEmpty() || yearParam.isEmpty()){
    		Constant.addError("La date de naissance n'est pas correcte !");
    		return null;
    	}
    	
    	else {
    	
    	String day = convertDay(dayParam);
    	String month = convertMonth(monthParam);
    	
    	
    	
    	Date d = dateFormat.parse(day + "/" + month + "/" + yearParam);
    	if (d.after(Calendar.getInstance().getTime()))
    		Constant.addError("La date de naissance de votre contact n'est pas encore venue !");
    	
    		return d;
    	}
    	
    	
    }
    
    private String convertDay(String dayParam) {
    	if (dayParam.length() == 1) {
    		return ("0" + dayParam);
    	}
    	else {
    		return dayParam;
    	}
    }
    
    private String convertMonth(String monthParam) {
    	Constant.fillDateStringToIntMap();
    	return Constant.dateStringToIntMap.get(monthParam);
    }
	
    private Adresse createAdresse(String typeAdresseParam, String numeroRueParam, String rueParam, String codePostalParam, String villeParam) {

    	if( typeAdresseParam.isEmpty() ) {
    		Constant.addError("Type d'adresse ne peut pas être vide ! ");
    		return null;
    	}
    	if( numeroRueParam.isEmpty() && rueParam.isEmpty() && codePostalParam.isEmpty() && villeParam.isEmpty() ) {
    		return null;
    	}
    	
    	Adresse adresse = new Adresse();
    	
    	adresse.setType(typeAdresseParam);
    	adresse.setNumero(numeroRueParam);
    	adresse.setRue(rueParam);
    	adresse.setCodePostal(codePostalParam);
    	adresse.setVille(villeParam);
    	
    	return adresse;

    }
    
	private String convertMonth(int monthParam) {
		Constant.fillDateIntToStringMap();
    	return Constant.dateIntToStringMap.get(monthParam);
    }
	

}
